<?php

declare(strict_types=1);

namespace App\Helper;

use App\Common\Status;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Exception\RequestException;
use JetBrains\PhpStorm\ArrayShape;

class GuzzleHttp
{
    /**
     * @param $url
     * @param int $timeout
     * @param array $extraOption
     * @return Client
     */
    public static function gHttps($url, $timeout = 2, $extraOption = []): Client
    {
        return new Client([
            'base_uri' => $url,
            'timeout'  => $timeout,
        ]);
    }


    /**
     * @param string $url
     * @param array $data
     * @param array $headers
     * @param int $timeOut
     * @param int $paramType
     * @return array
     * @throws GuzzleException
     */
    public static function GuzzlePost(
        string $url,
        array $data,
        $headers = [],
        int $timeOut = 2,
        int $paramType = 1
    ): array {
        # json参数
        $info['json'] = $data;

        $info['heard'] = [
            'Content-Type' => 'application/json'
        ];

        if ($paramType == 2) {
            # 普通参数
            $info['form_params'] = $data;
        } elseif ($paramType == 3) {
            # 二进制
            # $body = fopen('/path/to/file', 'r');
            # $body = \GuzzleHttp\Psr7\stream_for('hello!'); 创建流
            $info['body'] = (string)$data;
        }

        if ($headers && count($headers) > 0) {
            $info['heard'] = $headers;
        }


        try {
            $response = self::gHttps($url, $timeOut)->request(
                "post",
                "",
                $info
            );
            $contents = $response->getBody()->getContents();
            $code     = $response->getStatusCode(); // 200
            //        $code = $response->getReasonPhrase(); //200
            return ['contents' => $contents, 'code' => $code];

        } catch (RequestException $e) {
            return [
                'contents' => ['request' => $e->getRequest(), $e->hasResponse() ? $e->getResponse() : ""],
                'code'     => Status::ERROR
            ];

        }
    }


    /**
     * @param string $url
     * @param int $timeOut
     * @param array $query
     * @return array
     */
    public static function GuzzleGet(string $url, int $timeOut, array $query): array
    {
        try {
            $response = self::gHttps($url, $timeOut)->request(
                "get",
                '',
                $query
            );

            $code = $response->getStatusCode();

            $contents = $response->getBody()->getContents();

            return ['contents' => $contents, 'code' => $code];

        } catch (GuzzleException $e) {
            return [
                'contents' => ['request' => $e->getRequest(), $e->hasResponse() ? $e->getResponse() : ""],
                'code'     => Status::ERROR
            ];
        }

    }


    /**
     * @param string $url
     * @param array $body
     * @param array $headers
     * @param int $timeOut
     * @return array
     * @throws GuzzleException
     */
    public static function GuzzlePostNew(
        string $url,
        array $body,
        array $headers = [],
        int $timeOut = 2
    ): array {

        try {
            $client = new Client();

            $response = $client->post($url, [
                'headers' => $headers,
                'json'    => $body,   // 或 'form_params' => $body，根据需要选择
                'timeout' => $timeOut // 设置超时时间
            ]);

            $contents = $response->getBody()->getContents();
            $code     = $response->getStatusCode(); // 200
            //        $code = $response->getReasonPhrase(); //200
            return ['contents' => $contents, 'code' => $code];

        } catch (GuzzleException $e) {
            if ($e instanceof RequestException && $e->getResponse() !== null) {
                // 请求异常，获取响应内容
                $st = json_decode($e->getResponse()->getBody()->getContents(), true);
                return ['contents' => $st, 'code' => Status::ERROR];
            } else {
                // 连接异常，处理其他错误
                return ['contents' => '连接异常', 'code' => Status::ERROR];
            }
        }
    }

    /**
     * @param string $url
     * @param int $timeOut
     * @param array $headers
     * @param array $query
     * @return array
     */
    public static function GuzzleGetNew(string $url, int $timeOut, array $headers, array $query = []): array
    {
        try {
            $client = new Client();
            //            $headers = [
            //                'User-Agent' => 'MyCustomUserAgent',
            //                'Authorization' => 'Bearer myAccessToken',
            //                'Content-Type' => 'application/json',
            //                // 根据需要设置其他标头
            //            ];

            $response = $client->request('GET', $url, [
                'headers' => $headers,
                'query'   => $query,  // 设置查询参数
                'timeout' => $timeOut // 设置超时时间
            ]);

            $code = $response->getStatusCode();

            $contents = $response->getBody()->getContents();

            return ['contents' => $contents, 'code' => $code];

        } catch (GuzzleException $e) {
            $st = json_decode($e->getResponse()->getBody()->getContents(),true);
//            var_dump($st);
//            var_dump($e->getMessage());
            return [
                'contents' => $st,
                'code'     => Status::ERROR
            ];
        }

    }
}
